package com.ee.chat.api.task;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ee.chat.api.common.CommonService;
import com.ee.chat.common.dao.*;
import com.ee.chat.common.entity.Host;
import com.ee.chat.common.util.ConstantsUtil;
import com.ndhutu.ee.util.DateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Component
@Async
public class HostTask {
    private Logger log = LoggerFactory.getLogger(HostTask.class);

    @Resource(name = "stringRedisTemplate")
    StringRedisTemplate redisTemplate;
    @Resource
    HostMapper hostMapper;
    @Resource
    UserDynamicMapper userDynamicMapper;
    @Resource
    CommonService commonService;
    @Resource
    UserCreditLogMapper userCreditLogMapper;
    @Resource
    HostLevelConfigMapper hostLevelConfigMapper;
    @Resource
    UserCallLogMapper userCallLogMapper;

    /**
     * 刷新主播权重，每1分钟执行一次
     * @Author Shane
     * @Date 2019/7/2517:11
     * @param
     * @return
     **/
//    @Scheduled(cron = "0 0/1 * * * ?")
    public void updateHostWi(){
        if(!commonService.getIpStatus()){
            return;
        }

        List<Map<String, Object>> wis = hostMapper.getHostWi();
        String key = "host:hot:online";
        for(Map<String, Object> wi : wis){
            Integer num = Integer.parseInt(wi.get("wi")+"");
            double value = num * Math.random();

            String tempKey  = key+":"+wi.get("online");
            redisTemplate.opsForZSet().add(tempKey, wi.get("userId")+"", value);
        }

        log.info("热门主播数据已更新");
    }

    /**
     * 刷新动态权重，每5分钟执行一次
     * 动态权重=主播权重+时间权重
     * 时间权重默认为100，每5分钟减2
     * @Author Shane
     * @Date 2019/8/710:15
     * @param
     * @return
     **/
    @Scheduled(cron = "0 0/5 * * * ?")
    public void updateDynamicWi(){
        if(!commonService.getIpStatus()){
            return;
        }

        long page = 1, limit = 1000;
        Date now = new Date();

        List<String> ids = new ArrayList<>();

        while (limit >= 1000){
            Page<Map<String, Object>> p = new Page<>(page, limit);
            IPage<Map<String, Object>> iPage = userDynamicMapper.getHostDynamicWI(p);
            List<Map<String, Object>> dynamcis = iPage.getRecords();
            limit = iPage.getSize();

            for(Map<String, Object> dynamic : dynamcis){
                Date createTime = (Date) dynamic.get("createTime");
                int minute = (int)((now.getTime() - createTime.getTime()) / (1000*60));
                int timeWI = 100 - (minute / 5);
                if(timeWI < 0){
                    timeWI = 0;
                }

                int compWI = Integer.parseInt(dynamic.get("hostWI")+"") + timeWI;
                int id = Integer.parseInt(dynamic.get("id")+"");

                for(int i=0; i<compWI; i++){
                    ids.add(id+"");
                }
            }
        }

        String key = "dynamic:all";
        redisTemplate.expire(key, -1, TimeUnit.MINUTES);

        //乱序
        Collections.shuffle(ids);
        if(ids.size() > 0){
            redisTemplate.boundListOps(key).leftPushAll(ids.toArray(new String[ids.size()]));
        }

        log.info("主播动态已更新");
    }

    /**
     * 刷新主播等级，每天凌晨3点执行一次
     * 统计最近7天主播获得的总积分，从而进行升级（只升不降）
     * @Author Shane
     * @Date 2019/12/24 20:58
     * @param
     * @return
     **/
    @Scheduled(cron = "0 0 3 * * ?")
    public void updateHostLevel(){
        if(!commonService.getIpStatus()){
            return;
        }

        Calendar cal = Calendar.getInstance();
        Date endTime = cal.getTime();
        cal.add(Calendar.DAY_OF_YEAR, -7);
        Date beginTime = cal.getTime();

        List<Map<String, Object>> stats = userCreditLogMapper.getUserCreditStat(beginTime, endTime);
        for(Map<String, Object> stat : stats){
            double credit = Double.parseDouble(stat.get("credit")+"");
            int userId = Integer.parseInt(stat.get("userId")+"");

            int level = hostLevelConfigMapper.getUserLevel(credit);

            Host host = hostMapper.selectByUserId(userId);
            if(host != null && host.getLevel() < level){
                host.setLevel(level);
                hostMapper.updateById(host);
            }
        }

        log.info("主播等级已更新");
    }

    /**
     * 更新接通率，每天10点执行一次
     * @Author Shane
     * @Date 2019/12/24 20:58
     * @param
     * @return
     **/
    @Scheduled(cron = "0 0 3 * * ?")
    public void updateSuccessRate() throws Exception{
        if(!commonService.getIpStatus()){
            return;
        }

        Set<String> callKeys = redisTemplate.keys(ConstantsUtil.USER_CALL + "*");
        for(String callKey : callKeys){
            Map<Object, Object> call = redisTemplate.opsForHash().entries(callKey);
            Date latestTime = DateUtil.parse(call.get("latestTime")+"");
            if(new Date().getTime() - latestTime.getTime() < 1*24*3600*1000 ){
                //当天存在通话
                Integer userId = Integer.parseInt(callKey.replace(ConstantsUtil.USER_CALL, ""));

                Integer successRate = userCallLogMapper.getHostSuccessRate(userId);
                QueryWrapper<Host> wrapper = new QueryWrapper<>();
                wrapper.eq("user_id", userId);
                Host host = new Host();
                host.setSuccessRate(successRate);
                hostMapper.update(host, wrapper);
            }else{
                continue;
            }
        }
    }
}
